// MINIScript

#include <unistd.h>
#include <stdint.h>
#include "miniscript.config.h"

// you have to define these symbols
// MS_SIZE_POOLEDOBJ : object member max
// MS_SIZE_POOLEDARR : array length max
// MS_SIZE_VARNAME   : var name length max
// MS_SIZE_PROPNAME  : property name length max

extern const char E_STACK_OVERFLOW[];
extern const char E_SCOPE_OVERFLOW[];
extern const char E_TOO_LONG_NAME[];
extern const char E_COULDNT_NEW[];
extern const char E_COULDNT_CREATE[];
extern const char E_NOT_FOUND[];

typedef enum {
    VT_Undefined = 0,                       // 变量类型
    VT_Refer,
    VT_Number,
    VT_CodeString,
    VT_Function,
    VT_CodeFunction,
    VT_Object,
    VT_Char,
    
    VTX_Frame = 0x20,                       // 关键字
    VTX_Call,
    VTX_If,
    VTX_While,
    VTX_Try,
    VTX_Catch,
    VTX_Throw,
    VTX_CodeReturn,
    VTX_Params,
    VTX_Return,
    VTX_This,
} VarType;

typedef struct Var {
    // 1byte unused0;
    // 1byte unused1;
    // 1byte unused2;
    uint8_t vt;                             // 表示union具体哪个类型
    union {
        void (*func)();                     // 函数
        int32_t num;                        // 整型
        const char* code;                   // 字符型
        struct Var* ref;                    // 引用类型
        struct Object* obj;                 // 对象
    };
} Var;  // __attribute__((__packed__))
Var* Var_(Var* p);
VarType Var__(Var* p);

typedef struct Error {                      // 错误类型
    const char* code;                       // 错误代码
    size_t      len;                        // 代码长度
    const char* reason;                     // 错误原因
} Error;

typedef struct Stack {                      // 栈
    size_t size;                            // 栈大小
    size_t n;                               // 栈当前个数，每切换一个新的栈，n+1
    Error* e;                               // 错误信息
    Var vars[0];                            // 变量数组
} Stack;
extern Var Stack_OVERFLOW;
Stack* Stack_(Stack* p, size_t size);       // 栈对象
void Stack__(Stack* p);
Var* Stack_push(Stack* p);
Var* Stack_pop(Stack* p);
Var* Stack_tip(Stack* p, int n);
void Stack_ground(Stack* p);
Var* Stack_flatten(Stack* p);

typedef struct VarMap {                     // 变量映射表
    Var* pv;                                // 变量
    char name[MS_SIZE_VARNAME];             // 变量名
} VarMap;
typedef struct Scope {                      // 作用域链
    size_t size;                            // 作用域大小
    size_t n;                               // 作用域序号
    struct Scope* s;                        // 下一个作用域对象
    Error* e;                               // 错误信息
    VarMap nvars[0];                        // 变量映射
} Scope;
Scope* Scope_(Scope* p, size_t size);
void Scope__(Scope* p);
Var* Scope_add(Scope* p, const char* name, size_t len, Var* pv);

typedef struct NamedVar {                   // 变量
    Var var;                                // 变量值
    char name[MS_SIZE_PROPNAME];            // 变量名
} NamedVar;
typedef struct Object {                     // 对象类型
    void (*dctr)(struct Object*);           // 对象关系链
    uint16_t size;                          // 变量大小
    uint16_t c;                             // 
    NamedVar vars[0];                       // 变量数组
} Object;
Object* Object_retain(Object* p);           // 保持
size_t Object_release(Object* p);           // 释放

typedef struct ObjectForPool {              // 对象池
    Object base;                            // 原始对象
    NamedVar vars[MS_SIZE_POOLEDOBJ];       // 命名变量
} ObjectForPool;
typedef struct Pool {                       // 池
    size_t size;                            // 池子大小
    ObjectForPool objs[0];                  // 对象池
} Pool;
Pool* Pool_(Pool* p, size_t size);
void Pool__(Pool* p);
Pool* Pool_global(Pool* p);

typedef struct Thread {                     // 虚拟机上下文对象
    const char*   c;                        // 代码
    void        (*l)(struct Thread*);       // 虚拟机关联对象，作用在多线程环境，可以创建多个虚拟机对象，虚拟机嵌套时，就需要关联多个虚拟机对象
    Stack*        s;                        // 栈
    Scope*        o;                        // 作用域
    void        (*f)(struct Thread*, const char*, size_t, int);
    Error         e;                        // 错误
} Thread;
Thread* Thread_(Thread* p, const char* c, Stack* s, Scope* o);
void Thread__(Thread* p);
int Thread_walk(Thread* p);
Error* Thread_run(Thread* p);
void Thread_setCodeFunction(Thread* p, Var* pcf, size_t np, Var* ap);
Var* Thread_getLastExp(Thread* p);

// library
typedef struct Array {
    Object base;
    NamedVar vars[1];                       // for 0:length
    Var avars[0];
} Array;

typedef struct ArrayForPool {
    Array base;
    Var avars[MS_SIZE_POOLEDARR];
} ArrayForPool;
typedef struct ArrayPool {
    size_t size;
    ArrayForPool arrs[0];
} ArrayPool;
ArrayPool* ArrayPool_(ArrayPool* p, size_t size);
void ArrayPool__(ArrayPool* p);
ArrayPool* ArrayPool_global(ArrayPool* p);

void mslib_Array(Thread* p);
void dump(Stack *s);
void dumpo(Scope *o);

